﻿using DocumentFormat.OpenXml.Lite.Core.Interfaces;
using DocumentFormat.OpenXml.Lite.Core.Office;
using DocumentFormat.OpenXml.Lite.PresentationML.Presentation.SlideElements;
using DocumentFormat.OpenXml.Lite.Xml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using IO = System.IO;

namespace DocumentFormat.OpenXml.Lite.PresentationML.Presentation.Base
{
    [XmlRoot("sldMaster", Namespace = Constants.Presentation)]
    public class SlideMaster : XmlSerializable, ISerializable
    {
        [Optional]
        [XmlAttribute("preserve", Form = XmlSchemaForm.Qualified)]
        public Nullable<bool> Preserve { get; set; }

        [XmlElement("cSld", Namespace = Constants.Presentation)]
        public CommonSlideData SlideData { get; set; }

        [XmlElement("clrMap", Namespace = Constants.Presentation)]
        public ColorSchemeMap ColorSchemeMap { get; set; }

        [Optional]
        [XmlArray("sldLayoutIdLst", Namespace = Constants.Presentation)]
        [XmlArrayItem("sldLayoutId", Namespace = Constants.Presentation)]
        public XmlList<SimpleIdElement> SlideLayoutIds { get; set; }

        [Optional]
        [XmlElement("transition", Namespace = Constants.Presentation)]
        public Transition SlideTransition { get; set; }
        /*
        [Optional]
        [XmlElement("timing", Namespace = Constants.Presentation)]
        public Timing SlideTiming { get; set; }
        */
        [Optional]
        [XmlElement("hf", Namespace = Constants.Presentation)]
        public HeaderFooterInfo HeaderFooterInformation { get; set; }

        [Optional]
        [XmlElement("txStyles", Namespace = Constants.Presentation)]
        public TextStyles TextStyles { get; set; }

        [Optional]
        [XmlElement("extLst", Namespace = Constants.Presentation)]
        public ExtensionList ExtensionList { get; set; }

        [XmlNamespaceDeclarations]
        public XmlSerializerNamespaces Namespaces { get; set; }

        public SlideMaster()
        {
            Namespaces = new XmlSerializerNamespaces();
            Namespaces.Add("p", Constants.Presentation);
            Namespaces.Add("r", Constants.Relationship);
            Namespaces.Add("a", Constants.Graphic);

            SlideLayoutIds = new XmlList<SimpleIdElement>();
        }

        #region ISerializable members

        public byte[] Serialize()
        {
            XmlSerializer serializer = new XmlSerializer(this.GetType());
            using (var stream = new IO.MemoryStream())
            {
                using (var writer = new IO.StreamWriter(stream, Encoding.UTF8))
                {
                    using (var xwriter = XmlWriter.Create(writer))
                    {
                        xwriter.WriteStartElement("p", "sldMaster", Constants.Presentation);
                        foreach (var ns in Namespaces.ToArray())
                        {
                            if (ns.Name != "")
                            {
                                xwriter.WriteAttributeString("xmlns", ns.Name, null, ns.Namespace);
                            }
                        }
                        this.WriteXml(xwriter);
                    }
                    return stream.ToArray();
                }
            }
        }

        public void Deserialize(System.IO.Stream content)
        {
            using (var reader = XmlReader.Create(content))
            {
                reader.ReadToDescendant("sldMaster", Constants.Presentation);
                for (int i = 0; i < reader.AttributeCount; ++i)
                {
                    string s = reader.GetAttribute(i);
                    if (Constants.GetDefaultPrefix(s) != string.Empty)
                    {
                        Namespaces.Add(Constants.GetDefaultPrefix(s), s);
                    }
                }
                this.ReadXml(reader);
            }
        }

        #endregion
    }
}
